﻿#include "CGrid.h"
#include "CBird.h"
#include "CCell.h"
#include <cstdlib>
CGrid::CGrid(void):
	m_row(0),
	m_col(0),
	m_board(NULL),
	m_i(0),
	m_j(0),
	score(0),
	timer(0),
	sum(0)
{
}


CGrid::~CGrid(void)
{
}

CGrid* CGrid::init(int row,int col)
{
	
	CGrid *pGrid = new CGrid();
	pGrid->m_row = row;
	pGrid->m_col = col;
	//---cấp phát
	pGrid->m_board = new CCell*[col];
	for(int i=0;i<col;i++)
	{
		pGrid->m_board[i] = new CCell[row];
	}
	//--set touch
	pGrid->setTouchEnabled(true);
	//--init các cell trong board
	for(int i=0;i<col;i++)
		for(int j=0;j<row;j++)
		{
			pGrid->m_board[i][j].init(ccp(POSITION.x + i*C_WIDTH, POSITION.y + j*C_HEIGHT));	
			pGrid->m_board[i][j].setRowIndex(j);
			pGrid->m_board[i][j].setColIndex(i);
		}
	pGrid->generate();  
	pGrid->render(pGrid);
	return pGrid;
}

void CGrid::clearBoard()
{
	 
}

void CGrid::generate()  //tạo bird cho mỗi cell
{
	for(int i=0;i<m_col;i++)
		for(int j = 0;j<5;j++)
		{
			int temp = rand()%8;
			float time = (float)(rand()%20); // set time delay để play animation cho mỗi bird
			m_board[i][j].addNewElement(CBird::init(LIVE,(BIRD_COLOR)temp,time));
			m_board[i][j].getElement()->setPosition(m_board[i][j].getPosition());
		}

		for (int i = 0; i < m_col; i++) //set canCheckExplosion = false doi voi 3 hang bird dau tien ( duoi board)
		{
			for (int j = 0; j < 1; j++)
			{
				CBird* temp = (CBird*)m_board[i][j].getElement();
				temp->canCheckExplosion = false;
			}
		}
}

void CGrid::render(CCLayer *layer)
{
	for(int i=0;i<m_col;i++)
		for(int j = 0;j<m_row;j++)
		{
			if(this->m_board[i][j].getElement()!=NULL)
				layer->addChild(this->m_board[i][j].getElement(),1);
		}
		stateBG=CCSprite::create(s_sTex_Stage_BG);
		stateBG->setAnchorPoint(ccp(0,0));
		stateBG->setPosition(ccp(0,0));
		layer->addChild(stateBG,0);
}

bool CGrid::canMove(int x,int y)
{
	if(y<1)
		return false;
	if(x>0 && x < m_col-1 && y <m_row )
	{
		if(m_board[x-1][y].getElement()!=NULL && m_board[x+1][y].getElement()!=NULL && m_board[x][y+1].getElement()!=NULL )
			return false;
	}
	if(x==0)
	{
		if(m_board[x+1][y].getElement()!=NULL && m_board[x][y+1].getElement()!=NULL)
			return false;
	}
	if(x==m_col-1)
	{
		if(m_board[x-1][y].getElement()!=NULL && m_board[x][y+1].getElement()!=NULL)
			return false;
	}

	if(m_board[x][y].getElement())
	{
		CBird* temp = (CBird*)m_board[x][y].getElement();
		if(temp->isExplosion==true)
			return false;
	}
	return true;
}

void CGrid::registerWithTouchDispatcher()
{
	CCDirector::sharedDirector()->getTouchDispatcher()->addTargetedDelegate(this, 0, true);
}

bool CGrid::ccTouchBegan(CCTouch* pTouch, CCEvent* pEvent)
{
	CCPoint temp=pTouch->getStartLocationInView();
	temp=CCDirector::sharedDirector()->convertToGL(temp);
	for(int i=0;i<m_col;i++)
		for(int j=0;j<m_row;j++)
		{
			//--kiểm tra cell nào đang đc touch convertTouchToNodeSpaceAR(pTouch)
			if(m_board[i][j].getRect().containsPoint(temp)==true && m_board[i][j].getElement()!=NULL && canMove(i,j)==true)
			{
				//CBird* temp = (CBird*)m_board[i][j].getElement();
				//temp->canCheckExplosion = false;
				m_board[i][j].setIsTouch(true);
				//lưu lại index của cell đang đc touch
				m_i = i;
				m_j = j;
				return true;
			}
		}
		return false;
	
}

void CGrid::ccTouchMoved(CCTouch* pTouch, CCEvent* pEvent)
{
	CCPoint location = pTouch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
	m_board[m_i][m_j].getElement()->setPosition(location - ccp(C_WIDTH/2,C_HEIGHT/2)); //--move bird
}
void CGrid::ccTouchEnded(CCTouch* pTouch, CCEvent* pEvent)
{
	CCPoint location = pTouch->getLocationInView();
    location = CCDirector::sharedDirector()->convertToGL(location);
	int indexX=(location.x-POSITION.x)/C_WIDTH;
	int indexY=(location.y-POSITION.y)/C_HEIGHT;
	if(CCRectMake(POSITION.x, POSITION.y, C_WIDTH*m_col,C_HEIGHT*m_row).containsPoint(convertTouchToNodeSpaceAR(pTouch))==true) //kiểm tra touch còn trong board hay ko
	{
		if(m_board[indexX][indexY].getElement()==NULL) //nếu cell tại vị trí nhả touch còn trống
		{
			m_board[indexX][indexY].addNewElement(m_board[m_i][m_j].getElement());				
			m_board[m_i][m_j].removeElement();
		}
		else //nếu cell tại vị trí nhả touch đã tồn tại bird thi trả bird về chỗ cũ
		{
			m_board[m_i][m_j].getElement()->setPosition(m_board[m_i][m_j].getPosition());
		}
	}
	else //nếu nhả touch ra khỏi board thì trả bird về chỗ cũ
	{
		m_board[m_i][m_j].getElement()->setPosition(m_board[m_i][m_j].getPosition());
	}
	m_board[m_i][m_j].setIsTouch(false);
	m_i = m_j = 0;
}
void CGrid::update(float dt)// hàm update
{
	//-----------move Up tat ca bird moi 5 s----------
	if(m_j==0)
	{
		timer+=dt;
		if(timer > 5 )
		{
			timer = 0;
			
			for (int i = 0; i < m_col; i++)
				{
					for (int j = m_row-2; j >= 0; j--)
						{
							CBird* temp = (CBird*)m_board[i][j].getElement();
							if(temp!=NULL )
							{	
								m_board[i][j+1].addNewElement(temp);
								temp->setPosition(m_board[i][j].getPosition());
								temp->canCheckExplosion = true;

								CCMoveBy* moveUp=CCMoveBy::create(0.3,ccp(0,C_HEIGHT));
								temp->runAction(moveUp);
					
								m_board[i][j].removeElement();
								temp->canCheckExplosion = true;
							}
						}
				}
		
		//--------------Tao lai bird o hang dau tien---------------
			addNewRow(0);
		}
	}

	//----------- tao bird roi tu tren xuong -------------//

	if(m_board[0][10].getElement()==NULL)
	{
		addNewRow(10);
		for (int i = 0; i < m_col; i++)
		{
			CBird* tempBird = (CBird*)m_board[i][10].getElement();
			tempBird->m_canUpdate = false;
		}
		sum++;
	}

	for (int i = 0; i < m_col; i++)
	{
		CBird* tempBird = (CBird*)m_board[i][10].getElement();
		if(tempBird)
		{
			if(score / sum > 20)
			{
				tempBird->m_canUpdate =  true;
			}
		}
	}

	//-----------------------------
	for(int i=0;i<m_col;i++)
		for(int j=1;j<m_row;j++)
		{
			CBird* temp = (CBird*)m_board[i][j].getElement();

			if(temp)
			{
				temp->UpdateAnimation(dt);
			}
			if(m_j==0 && m_board[i][j].getElement()!=NULL && m_board[i][j-1].getElement()==NULL && temp->m_canUpdate == true)// xét xem nếu cell tại (i,j) có hay ko,
																					// nếu có thì xét xem cell phía dưới có hay ko,
																					// nếu cell dưới null thì moveby 1 đoạn đúng bằng
																					// độ dài của cái cell dưới
																					// gọi update ở hàm init
			{
				temp->canCheckExplosion = false;
				m_board[i][j-1].addNewElement(m_board[i][j].getElement());
				m_board[i][j].removeElement();	
				
				if(m_board[i][j-2].getElement()!=NULL)
				{
					temp->canCheckExplosion = true;
				}
			}
			
		}
		updateExplosion(dt);
}

void CGrid::updateExplosion(float dt)
{
	for (int i = 0; i < m_col; i++)
	{
		for (int j = 1; j < m_row; j++)
		{
			checkExplosion(i,j);
		}
	}
	for (int i = 0; i < m_col; i++)
		{
			for (int j = 1; j < m_row; j++)
			{
				if(m_board[i][j].getElement())
				{
					CBird* tempBird = (CBird*)m_board[i][j].getElement();
					if(tempBird->isExplosion==true)
					{
						tempBird->timer++;
						if(tempBird->timer%2==0)
							tempBird->setPosition(tempBird->getPosition() + ccp(2,0));
						else
							tempBird->setPosition(tempBird->getPosition() + ccp(-2,0));
						if(tempBird->timer > 100)
						{
							score++;
							removeChild(m_board[i][j].getElement());
							m_board[i][j].removeElement();
						}
					}
				}
			}
		}



}

bool CGrid::checkExplosion(int i,int j)  //kiem tra 4 bird ben canh, tinh so bird co mau giong nhau...blah blah
{
	int count = 0;
	int color;
	CBird* temp=(CBird*)m_board[i][j].getElement();
	CBird* temp1=NULL;
	CBird* temp2=NULL;
	CBird* temp3=NULL;
	CBird* temp4=NULL;
	if(temp!=NULL && temp->canCheckExplosion==true)
	{
		color = temp->GetColor();

		if(i > 0)
		{
			temp4 = (CBird*)m_board[i-1][j].getElement();
			if(temp4!=NULL && temp4->canCheckExplosion==true )
			{		
				if(temp4->GetColor()==color)
				{
					temp4->timer = temp->timer;
					count++;
				}
			}
		}

		if(j > 0)
		{
			temp1 = (CBird*)m_board[i][j-1].getElement();
			if(temp1!=NULL && temp1->canCheckExplosion==true)
			{		
				if(temp1->GetColor()==color)
				{
					temp1->timer = temp->timer;
					count++;
				}
			}
		}

		if(i < m_col-1)
		{
			temp2 = (CBird*)m_board[i+1][j].getElement();
			if(temp2!=NULL && temp2->canCheckExplosion==true)
			{		
				if(temp2->GetColor()==color)
				{
					temp2->timer = temp->timer;
					count++;
				}
			}
		}

		if(j < m_row-1)
		{
			temp3 = (CBird*)m_board[i][j+1].getElement();
			if(temp3!=NULL && temp3->canCheckExplosion==true)
			{			
				if(temp3->GetColor()==color)
				{
					temp3->timer = temp->timer;
					count++;
				}
			}
		}

		if(count<2)
		{
			return false;
		}
		else
		{
			temp->isExplosion = true;
			if(temp1!=NULL && temp1->GetColor()==color)
				temp1->isExplosion=true;
			if(temp2!=NULL && temp2->GetColor()==color)
				temp2->isExplosion=true;
			if(temp3!=NULL && temp3->GetColor()==color)
				temp3->isExplosion=true;
			if(temp4!=NULL && temp4->GetColor()==color)
				temp4->isExplosion=true;
			return true;
		}
			
	}

	return false;

}

void CGrid::addNewRow(int num)  //tao moi 1 hang bug o hang thu num
{
	for (int i = 0; i < m_col; i++)
			{
					int temp = rand()%8;
					float time = (float)(rand()%20); 
					m_board[i][num].addNewElement(CBird::init(LIVE,(BIRD_COLOR)temp,time));
					CBird* tempBird = (CBird*)m_board[i][num].getElement();
					tempBird->canCheckExplosion = false;
					this->addChild(tempBird,1);
			}
}